package com.winchain.chainbill.acct.service.impl;

import com.shell.bee.acct.account.po.AcctBas;
import com.shell.bee.acct.account.po.AcctBkp;
import com.shell.bee.acct.transaction.dao.AcctTxWdrlDao;
import com.shell.bee.acct.transaction.po.AcctTxRec;
import com.shell.bee.acct.transaction.po.AcctTxWdrl;
import com.shell.bee.acct.transaction.service.AcctTxWdrlService;
import com.shell.bee.base.exception.UnCheckMsgException;
import com.shell.bee.base.utils.DateUtil;
import com.shell.bee.base.utils.SpringContextUtil;
import com.shell.bee.base.utils.StringUtil;
import com.shell.bee.base.utils.SystemUtil;
import com.shell.bee.entity.auth.AuthOrgan;
import com.shell.bee.entity.mvc.RetMsg;
import com.shell.bee.persistence.annotation.Pagination;
import com.shell.bee.persistence.model.PageLimit;
import com.shell.constant.rel.AssetCode;
import com.shell.framework.utils.CommonDataUtil;
import com.shell.framework.utils.MessageSender;
import com.shell.framework.utils.SysDateUtil;
import com.shell.governor.modules.message.keyword.WithdrawKeyword;
import com.shell.stellar.service.StellarAcctService;
import com.winchain.chainbill.acct.dao.MyAcctDao;
import com.winchain.chainbill.acct.service.MyAcctService;
import com.winchain.chainbill.acct.vo.AcctVo;
import com.winchain.chainbill.acct.vo.ChainTxVo;
import com.winchain.chainbill.basic.cus.po.CusRec;
import com.winchain.chainbill.basic.cus.service.CusGrpService;
import com.winchain.chainbill.trade.service.BillAcctBlcService;
import com.winchain.chainbill.trade.service.BillAcctService;
import com.winchain.chainbill.trade.service.TradeService;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service("myAcctService")
public class MyAcctServiceImpl implements MyAcctService {
	@Autowired
	private MyAcctDao myAcctDao;
	@Autowired
	private TradeService tradeService;
	@Autowired
	private AcctTxWdrlDao acctTxWdrlDao;
	@Autowired
	private AcctTxWdrlService trdTxWdrlService;
	@Autowired
	private BillAcctService billAcctService;
	@Autowired
	private StellarAcctService stellarAcctService;
	@Autowired
	private BillAcctBlcService billAcctBlcService;
	@Autowired
	private CusGrpService cusGrpService;

	@Pagination
	public List<AcctTxRec> getAcctTx(PageLimit pageLimit, String acctNo, String txType, String txDateStart,
			String txDateEnd) {
		return this.myAcctDao.getAcctTx(acctNo, txType, txDateStart, txDateEnd);
	}

	public void withdraw(AcctTxRec txRec, String grpId) {
		String cusId = CommonDataUtil.getCurEntId();

		AcctTxWdrl txWdrl = new AcctTxWdrl();
		txWdrl.setWdrlId(SystemUtil.getUUID());
		txWdrl.setAcctNo(txRec.getTxAcctNo());
		txWdrl.setWdrlDate(DateUtil.getSystemDate());
		txWdrl.setCustId(cusId);
		txWdrl.setCustNm(CommonDataUtil.getCurEntName());
		txWdrl.setCardNm(txRec.getCpAcctNm());
		txWdrl.setCardNo(txRec.getCpAcctNo());
		txWdrl.setWdrlAmt(txRec.getTxAmt());

		txWdrl.setWdrlState("1");
		txWdrl.setApprover(grpId);
		txWdrl.setBankNm(txRec.getCpBankNm());
		txWdrl.setRemark(txRec.getTxAbs());
		this.acctTxWdrlDao.insert(txWdrl);

		txRec.setBizId(txWdrl.getWdrlId());
		txRec.setOptType("qt_blk");
		txRec.setTxType("1");
		txRec.setTxSts("S");

		AcctBkp txBkp = this.billAcctBlcService.getAcctBkp(txRec.getTxAcctNo(), AssetCode.CNY.name(), grpId, null);
		txRec.setTxBkpId(txBkp.getBkpId());
		if (StringUtil.empty(txRec.getTxId())) {
			txRec.setTxId(SystemUtil.getUUID());
		}
		txRec.setAcctin(false);
		this.tradeService.callback(txRec);

		String template = "MT04000";
		WithdrawKeyword keyWord = new WithdrawKeyword();
		keyWord.setTxAmt(txWdrl.getWdrlAmt().toString());
		keyWord.setApplyDate(DateUtil.parseDate(txWdrl.getWdrlDate(), "yyyyMMdd", "yyyy-MM-dd"));
		keyWord.setCusName(CommonDataUtil.getCurEntName());
		String senderId = CommonDataUtil.getUserId();

		List<CusRec> admins = this.cusGrpService.findGroupEnts(grpId, "GROUP_ADMIN");
		for (CusRec admin : admins) {
			MessageSender.sendMessageByTmpl(senderId, template, keyWord, admin.getCusId());
		}
	}

	@Pagination
	public List<AcctTxWdrl> getWithdrawList(PageLimit pageLimit, String cusName, String wdrlState,
			String applyDateStart, String applyDateEnd, String[] approvers) {
		if (approvers == null) {
			return new ArrayList();
		}
		cusName = StringUtil.getParameterLike(cusName);
		return this.acctTxWdrlDao.getWithdrawList(cusName, wdrlState, approvers, applyDateStart, applyDateEnd);
	}

	public RetMsg withdrawPass(String wdrlIds) {
		String[] idArr = wdrlIds.split(",");
		AcctTxWdrl wdrl = null;
		int changeCount = 0;
		for (String id : idArr) {
			wdrl = this.acctTxWdrlDao.lockByKey(id);
			if (!"1".equals(wdrl.getWdrlState())) {
				changeCount++;
			} else {
				String grpId = wdrl.getApprover();
				AcctTxRec acctTxRec = getCommonAcctTxRec(wdrl);
				acctTxRec.setTxAbs("����������������");
				acctTxRec.setTxType("1");

				acctTxRec.setOptType("2".equals(wdrl.getWdrlState()) ? "qt_trd" : "qt_wtd");
				acctTxRec.setCurrCode(AssetCode.CNY.name());
				acctTxRec.setTxChnCode("B");

				AcctBas txAcct = this.billAcctService.getCard(wdrl.getAcctNo());
				acctTxRec.setTxAcctNo(txAcct.getAcctNo());
				acctTxRec.setTxAcctNm(txAcct.getAcctNm());
				acctTxRec.setTxBankNm(txAcct.getFiNm());
				AcctBkp txAcctBkp = this.billAcctBlcService.getAcctBkp(acctTxRec.getTxAcctNo(), acctTxRec.getCurrCode(),
						grpId, null);
				acctTxRec.setTxBkpId(txAcctBkp.getBkpId());

				acctTxRec.setCpAcctNo(wdrl.getCardNo());
				acctTxRec.setCpAcctNm(wdrl.getCardNm());
				acctTxRec.setCpBankNm(wdrl.getBankNm());
				AcctBkp cpAcctBkp = this.billAcctBlcService.getAcctBkp(acctTxRec.getCpAcctNo(), acctTxRec.getCurrCode(),
						null, null);
				acctTxRec.setCpBkpId(cpAcctBkp.getBkpId());
				acctTxRec.setTxReqFiCls("2");
				Map<String, String> ret = this.tradeService.fire(acctTxRec);
				if (!"S".equals(ret.get("ret_code"))) {
					return new RetMsg("error", "��������������" + (String) ret.get("ret_msg"));
				}
				wdrl.setWdrlState("2");
				this.trdTxWdrlService.updateNotNull(wdrl);

				String template = "MT04001";
				WithdrawKeyword keyWord = new WithdrawKeyword();
				keyWord.setTxAmt(wdrl.getWdrlAmt().toString());
				keyWord.setApplyDate(DateUtil.parseDate(wdrl.getWdrlDate(), "yyyyMMdd", "yyyy-MM-dd"));
				String senderId = CommonDataUtil.getUserId();

				MessageSender.sendMessageByTmpl(senderId, template, keyWord, wdrl.getCustId());
			}
		}
		if (changeCount > 0) {
			String msg = "������������������������";
			if (changeCount > 1) {
				msg = "����������������������������";
			}
			return new RetMsg("error", msg);
		}
		return new RetMsg("success", false, "������������");
	}

	public RetMsg withdrawReject(String wdrlIds, String remark) {
		String[] idArr = wdrlIds.split(",");
		AcctTxWdrl wdrl = null;
		int changeCount = 0;
		for (String id : idArr) {
			wdrl = this.acctTxWdrlDao.lockByKey(id);
			String wdrlState = wdrl.getWdrlState();
			if (!"1".equals(wdrlState)) {
				changeCount++;
			} else {
				String grpId = wdrl.getApprover();
				AcctTxRec acctTxRec = getCommonAcctTxRec(wdrl);
				acctTxRec.setTxAbs("��������������������������" + wdrl.getRemark());
				acctTxRec.setTxType("1");
				acctTxRec.setOptType("qt_ubk");
				acctTxRec.setCurrCode(AssetCode.CNY.name());

				AcctBas txAcct = this.billAcctService.getCard(wdrl.getAcctNo());
				acctTxRec.setTxAcctNo(txAcct.getAcctNo());
				acctTxRec.setTxAcctNm(txAcct.getAcctNm());
				acctTxRec.setTxBankNm(txAcct.getFiNm());
				AcctBkp txAcctBkp = this.billAcctBlcService.getAcctBkp(acctTxRec.getTxAcctNo(), AssetCode.CNY.name(),
						grpId, null);
				acctTxRec.setTxBkpId(txAcctBkp.getBkpId());

				acctTxRec.setAcctin(false);
				this.tradeService.callback(acctTxRec);

				wdrl.setWdrlState("0");
				wdrl.setRemark(remark);
				this.trdTxWdrlService.updateNotNull(wdrl);

				String template = "MT04002";
				WithdrawKeyword keyWord = new WithdrawKeyword();
				keyWord.setTxAmt(wdrl.getWdrlAmt().toString());
				keyWord.setApplyDate(DateUtil.parseDate(wdrl.getWdrlDate(), "yyyyMMdd", "yyyy-MM-dd"));
				keyWord.setRemark(remark);
				String senderId = CommonDataUtil.getUserId();
				MessageSender.sendMessageByTmpl(senderId, template, keyWord, wdrl.getCustId());
			}
		}
		if (changeCount > 0) {
			String msg = "������������������������";
			if (changeCount > 1) {
				msg = "����������������������������";
			}
			return new RetMsg("error", msg);
		}
		return new RetMsg("success", false, "����������������");
	}

	private AcctTxRec getCommonAcctTxRec(AcctTxWdrl trdTxWdrl) {
		AcctTxRec txRec = new AcctTxRec();
		txRec.setTxId(SystemUtil.getUUID());
		txRec.setTxId(SystemUtil.getUUID());
		txRec.setTxSn(SystemUtil.getUUID());
		txRec.setBizId(trdTxWdrl.getWdrlId());
		txRec.setTxAmt(trdTxWdrl.getWdrlAmt());
		txRec.setTxDt(SysDateUtil.getSystemDate());
		txRec.setTxTs(SysDateUtil.getSystemDateTime());
		txRec.setTxSts("S");
		String sourceCode = SpringContextUtil.getProperty("system.code");
		txRec.setSrcCode(sourceCode);
		txRec.setDataScLvl("B");
		txRec.setTxCashFlag("N");
		txRec.setTxReqFiCls("1");
		txRec.setTxOperator("System");
		return txRec;
	}

	public AcctVo getSettleAcct() {
		String cusId = CommonDataUtil.getCurEntId();
		String acctType = "1";
		String acctState = "N";
		String useCode = "00";
		return this.myAcctDao.getSettleAcct(cusId, acctType, acctState, useCode);
	}

	public List<AcctTxWdrl> getWithdrawList(String cusId) {
		return this.acctTxWdrlDao.getWithdrawList(null, "1", null, null, cusId);
	}

	public Map<String, BigDecimal> getAcctTxStat(String acctNo, String txType, String txDateStart, String txDateEnd) {
		acctNo = StringUtil.getParameterLike(acctNo);
		return this.myAcctDao.getAcctTxStat(acctNo, txType, txDateStart, txDateEnd);
	}

	public void recharge(AcctTxRec txRec, String grpId) {
		txRec.setTxId(SystemUtil.getUUID());
		txRec.setTxSn(SystemUtil.getUUID());
		txRec.setTxType("0");
		txRec.setOptType("qt_inc");
		txRec.setCurrCode(AssetCode.CNY.name());
		txRec.setDataScLvl("B");
		txRec.setTxDt(SysDateUtil.getSystemDate());
		txRec.setTxTs(SysDateUtil.getSystemDateTime());

		AcctBkp txBkp = this.billAcctBlcService.getAcctBkp(txRec.getTxAcctNo(), AssetCode.CNY.name(), null, null);
		txRec.setTxBkpId(txBkp.getBkpId());
		AcctBkp cpBkp = this.billAcctBlcService.getAcctBkp(txRec.getCpAcctNo(), AssetCode.CNY.name(), grpId, null);
		txRec.setCpBkpId(cpBkp.getBkpId());

		txRec.setAcctin(false);
		this.tradeService.callback(txRec);
	}

	@Pagination
	public List<ChainTxVo> getChainTx(PageLimit pageLimit, String acctNo, String billCode, String txType) {
		acctNo = StringUtil.getParameterLike(acctNo);
		return this.myAcctDao.getChainTx(acctNo, billCode, txType);
	}

	public Map<String, Map<String, String>> getChainAssets() {
		AuthOrgan organ = CommonDataUtil.getCurEnt();

		AcctBas bas = this.billAcctService.getAcctBas(organ.getOrganId(), "1", null);

		Map<String, String> assets = null;
		Map<String, Map<String, String>> rs = new HashMap();
		try {
			Map<String, String> tmp = this.stellarAcctService.getAcctBlc(bas.getAcctNo());
			for (String assetCode : tmp.keySet()) {
				if (null != assetCode) {
					if (null == assets) {
						assets = new HashMap();
					}
					assets.put(assetCode, tmp.get(assetCode));
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
			throw new UnCheckMsgException("������������������!");
		}
		rs.put(bas.getAcctNo(), assets);
		return rs;
	}

	public List<AcctVo> getGrpAcctBlc(String cusId) {
		return this.myAcctDao.getGrpAcctBlc(cusId);
	}
}
